#include <iostream>
using namespace std;
#include <vector>
#ifndef __WORK_STACK__
#define __WORK_STACK__
#include "my_hash.h"
#include "variable_define.h"
#include "token_define.h"
#include "translate_list.h"
//算符优先级表   [栈内][栈外]   栈外25为#，优先级最低
const short token_level[25][26] = {
	{ 1, 	 1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 1, 	 1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	-1, 	-1, 	-1, 	-1, 	 1, 	-1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	-1, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 1, 	 1, 	 0, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	 2, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	 0, 	 0, 	 2, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	-1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 2, 	 0, 	 0, 	-1, 	 1, 	-1, 	-1, 	-1, 	-1, 	 0,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	-1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	 1, 	-1, 	-1, 	-1, 	-1, 	 0,  	 1},
	{-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	-1, 	-1, 	-1, 	-1, 	 0, 	-1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 2, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	-1,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	-1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	 1, 	-1, 	-1, 	-1, 	-1, 	 0,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	-1, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	 0, 	 0, 	-1, 	 0, 	 0, 	-1, 	 0, 	 0, 	 2, 	-1, 	-1, 	-1, 	-1, 	-1,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	 0,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	 0,  	 1},
	{ 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	-1, 	 0,  	 1},
	{ 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0,  	 1},
	{ 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 1, 	 1, 	 1, 	 1, 	 1, 	 0, 	 1, 	 0, 	 1, 	 0, 	 0, 	 1, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0, 	 0,  	 1}
};
// 优先级工作栈
// @variable start_location  存储‘｛ ’进栈时栈顶元素位置
// @variable symbol_stack    算符栈
// @variable var_stack		  变量栈
class work_stack{
	private:
		hash_table hash;
		translate_list list;
		int start_location; 
		vector<int> duan_top; 
		vector<int> while_flag;
		vector<string> value_stack;
		int IP_number;
		int layout_number;
		int temp_var_number;
		vector<TOKEN> symbol_stack;
		vector<int> var_stack;
		void insert_variable(int type);
		void insert_value(string value);
		void insert_symbol(TOKEN token);
		bool reduce(TOKEN token);
		void pop_symbol();
		void pop_var();
		void pop_value();
		bool pop_DUAN();
		void make_node(string &temp_var, int temp_var_number);
	public:
		work_stack();
		bool try_insert(TOKEN token);
		bool if_succeed();	
};

#endif
